#ifndef ClientSession_h__
#define ClientSession_h__
#include <boost/asio.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/array.hpp>
#include <list>
#include "IObject/StdCmm.h"

class  IPacketCodec;
struct SendBuffer;
struct RawPacket;
class  ILogger;

class ClientSession : public boost::enable_shared_from_this<ClientSession>,
				   public boost::noncopyable
{
public:
	ClientSession(boost::shared_ptr<boost::asio::ip::tcp::socket> pSocket,
		SocketID socketID, IPacketCodec* pCodec);

	virtual ~ClientSession();

public:
	SendResult AsyncSend(const char *pBuffer, int size);
	SendResult SyncSend(const char *pBuffer, int size);

	void Close( bool bClear = false);
	bool IsAlive();

	void Connect(std::string ip, unsigned short port, const MessageHandler & handler);
	boost::shared_ptr<boost::asio::ip::tcp::socket> Socket();
	time_t GetLastRecvTime();

	void Reconnect();

protected:
	void RealClose();
	void PacketCompleteCallback(RawPacket* pPacket);
	void DoAsyncSend();
	void OnAsyncSendComplete(const boost::system::error_code & e,
		size_t bytes_transferd);

	void OnAsyncConnected(const boost::system::error_code & e);

	void Read();

	void OnAsyncRead(const boost::system::error_code & e,
		size_t bytes_transferd);

protected:
	boost::shared_ptr<boost::asio::ip::tcp::socket> m_pSocket;
	SocketID m_SocketID;
	bool	 m_bClosed;

	IPacketCodec* m_pPacketCodec;

	boost::mutex		   m_lock;
	std::list<SendBuffer*> m_SendBufferList;
	uint32_t			   m_BatchSendCount;

	boost::array<char,8192>	m_RecvBuffer;
	std::string				m_RecvCache;
	time_t					m_LastRecv;

	MessageHandler			m_handler;

	std::string				m_strIP;
	uint16_t				m_sPort;
	ILogger*				m_pLogger;
};
#endif // ClientSession_h__
